/*-------------------------------------------------------------------------
 *
 * pgsleep.c
 *	   可移植的延迟处理。
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 *
 * src/port/pgsleep.c
 *
 *-------------------------------------------------------------------------
 */
#include "c.h"

#include <unistd.h>
#include <sys/time.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

/*
 * 在Windows后端，我们不使用这个实现，而是使用
 * src/backend/port/win32/signal.c中的信号感知版本。
 */
#if defined(FRONTEND) || !defined(WIN32)

/*
 * pg_usleep --- 延迟指定的微秒数。
 *
 * 注意：尽管延迟以微秒为单位指定，但在大多数Unix系统上，有效
 * 分辨率仅为1/HZ，或10毫秒。期望
 * 请求的延迟四舍五入到下一个分辨率边界。
 *
 * 在“long”为32位的机器上，最大延迟约为2000秒。
 *
 * 注意：当信号在睡眠期间到达时，其行为与平台
 * 有关。在大多数Unix类平台上，信号不会终止
 * 睡眠；但在某些平台上，它会（Windows实现也允许信号
 * 终止pg_usleep）。还有一些平台，不仅信号不终止
 * 睡眠，而且会实际重置超时计数器
 * 使睡眠实际上重新开始！因此，对于长时间的睡眠来说使用这个
 * 是相当危险的；持续的信号事件流可能会
 * 防止睡眠结束。长时间睡眠的更好做法
 * 是使用WaitLatch()和超时。
 */
void pg_usleep(long fc_microsec)
{
	if (fc_microsec > 0)
	{
#ifndef WIN32
		struct timeval fc_delay;

		fc_delay.tv_sec = fc_microsec / 1000000L;
		fc_delay.tv_usec = fc_microsec % 1000000L;
		(void) select(0, NULL, NULL, NULL, &fc_delay);
#else
		SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE);
#endif
	}
}

#endif							/* defined(FRONTEND) || !defined(WIN32) */
